//
//  HKRulerViewController.m
//  HKOCRuler
//
//  Created by lbxia on 2018/11/23.
//  Copyright © 2018年 lbx. All rights reserved.
//

#import "HKRulerViewController.h"
#import <SceneKit/SceneKit.h>
#import <ARKit/ARKit.h>
#import <Photos/Photos.h>
#import "LineNode.h"
#import "Plane.h"
#import "FocusSquare.h"
#import "ARSCNView+HKRuler.h"
#import "PlaneDetector.h"
#import "HKTool.h"


@interface HKRulerViewController ()<ARSCNViewDelegate,ARSessionDelegate>
@property (weak, nonatomic) IBOutlet UIView *backView;
@property (nonatomic, strong) ARSCNView *sceneView;

@property (weak, nonatomic) IBOutlet UIImageView *indicator;
@property (weak, nonatomic) IBOutlet UIButton *placeButton;
@property (weak, nonatomic) IBOutlet UIButton *photoBtn;
@property (weak, nonatomic) IBOutlet UIButton *trashButton;
@property (weak, nonatomic) IBOutlet UIButton *resetButton;

@property (nonatomic, strong) LineNode *line;
@property (nonatomic, strong) SCNNode *cameraNode;
@property (nonatomic, strong) NSMutableArray<LineNode*> *lines;

@property (nonatomic, strong) NSMutableDictionary<ARPlaneAnchor*,Plane*> *planes;

@property (nonatomic, strong) FocusSquare *focusSquare;

@property (nonatomic, assign) BOOL showDebugVisuals;

//是否显示特征点,默认显示
@property (nonatomic, assign) BOOL showFeaturePoints;

@property (nonatomic, assign) CVPixelBufferRef pixelBuffer;

@end

@implementation HKRulerViewController


#pragma mark- liftCycle
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    _showDebugVisuals = NO;
    _showFeaturePoints = YES;
    
    _sceneView = [[ARSCNView alloc]init];
    _sceneView.delegate = self;
    
    [self setupFocusSquare];
    
    self.cameraNode = [[SCNNode alloc]init];
    
    self.indicator.image = [UIImage imageNamed:@"HKRuler.bundle/addIndicator"];
    self.indicator.backgroundColor = [UIColor clearColor];
    
    [self.photoBtn setImage:[UIImage imageNamed:@"HKRuler.bundle/camera"] forState:UIControlStateNormal];
    self.photoBtn.backgroundColor = [UIColor clearColor];
    
    [self.placeButton setImage:[UIImage imageNamed:@"HKRuler.bundle/add"] forState:UIControlStateNormal];
    self.placeButton.backgroundColor = [UIColor clearColor];
    
    [self.resetButton setImage:[UIImage imageNamed:@"HKRuler.bundle/refresh"] forState:UIControlStateNormal];
    self.resetButton.backgroundColor = [UIColor clearColor];
    
    [self.trashButton setImage:[UIImage imageNamed:@"HKRuler.bundle/trash"] forState:UIControlStateNormal];
    self.trashButton.backgroundColor = [UIColor clearColor];
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    
    _sceneView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    [self.backView addSubview:_sceneView];

    
    [self restartSession];
}





#pragma mark- plan private

- (void)restartSession
{
    ARWorldTrackingConfiguration *configuration = [[ARWorldTrackingConfiguration alloc]init];
    
    configuration.planeDetection = ARPlaneDetectionHorizontal;
    
    [_sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking | ARSessionRunOptionRemoveExistingAnchors];
    
    if (_showFeaturePoints) {
        
        _sceneView.debugOptions = ARSCNDebugOptionShowFeaturePoints;
    }
    
    _sceneView.session.delegate = self;
    
    [_line removeFromParent];
    self.line = nil;
    
    for (LineNode *line in self.lines) {
        [line removeFromParent];
    }
    [self.lines removeAllObjects];
    
    [self updateView:NO];

}

- (void)updateView:(BOOL)state
{
    _placeButton.enabled = state;
    _indicator.tintColor = state ? [UIColor colorWithRed:149/255.0 green:210/255.0 blue:107/255.0 alpha:1.0] : [UIColor colorWithRed:223/255.0 green:53/255.0 blue:46/255.0 alpha:1.0];
    
    _indicator.backgroundColor = state ? [UIColor clearColor] : [UIColor colorWithDisplayP3Red:1 green:0 blue:0 alpha:0.4];
    
}

#pragma mark- Planes

- (void)addPlaneWithNode:(SCNNode*)node anchor:(ARPlaneAnchor*)anchor
{
    Plane *plane = [[Plane alloc]initWithAnchor:anchor showDebugVisualization:_showDebugVisuals];
    
    self.planes[anchor] = plane;
    
    [node addChildNode:plane];
}

- (void)updatePlaneWithAnchor:(ARPlaneAnchor*)anchor
{
    Plane *plane = self.planes[anchor];
    if (plane) {
        [plane updateWithAnchor:anchor];
    }
}

- (void)removePlane:(ARPlaneAnchor*)anchor
{
    Plane *plane = [self.planes objectForKey:anchor];
    if (plane) {
         [plane removeFromParentNode];
         [self.planes removeObjectForKey:anchor];
    }
}

#pragma mark- 按钮事件

- (IBAction)placeAction:(UIButton*)sender {
    
    [self buttonAnimated:sender];
    
    sender.selected = !sender.isSelected;
    
    if (_line == nil) {
        
        WorldPostion *ps = [self worldPositionFromScreenPosition:_indicator.center objectPos:SCNVector3Zero infinitePlane:NO];
        
        if (ps && !SCNVector3EqualToVector3(ps.position, SCNVector3Zero)) {
//        if (ps ) {

            SCNVector3 p = ps.position;
            
            self.line = [[LineNode alloc]initWithStartPos:p sceneV:_sceneView cameraNode:_cameraNode];
            
            self.line.idx = self.lines.count + 1;
        }
    }
    else
    {
        [self.lines addObject:self.line];
        
        self.line = nil;
    }
}

- (IBAction)deleteAction:(UIButton*)sender {
    
    [self buttonAnimated:sender];

    if (_line ) {
        [_line removeFromParent];
        _line = nil;
    }else{
        [_lines.lastObject removeFromParent];
        if (_lines.lastObject) {
            
            [_lines removeLastObject];
        }
    }
}

- (IBAction)restartAction:(UIButton*)sender {
    
    [self buttonAnimated:sender];

    [self restartSession];
}

- (IBAction)saveImgAction:(UIButton*)sender {
    
    [self authorizeWithCompletion:^(BOOL granted, BOOL firstTime) {
        
        if (granted) {

            [HKTool showHudWatingWithMessage: @"保持手机不动，图片保存中"];
            
            if (self.sceneView.debugOptions == ARSCNDebugOptionShowFeaturePoints) {
                
                self.sceneView.debugOptions = SCNDebugOptionNone;
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    
                    [self saveRenderImage];
                });
                
            }else
            {
                [self saveRenderImage];
            }
        }else{
             [HKTool showToastWithMessage:@"   没有相册权限，请前往设置权限   "];
        }
    }];
}

- (void)buttonAnimated:(UIButton*)btn
{
    //按钮动画效果，暂时不做
}

- (void)saveRenderImage
{
    //绘制线段后的图像
    UIImage *renderedImg = [_sceneView snapshot];
    
    //隐藏线段
    [self hiddenLineNode:YES];
    
    UIImage *originImg = [_sceneView snapshot];
    
    [self saveAlbumWith:renderedImg];
    [self saveAlbumWith:originImg];
    
    //显示线段
    [self hiddenLineNode:NO];
    
    if (_showFeaturePoints) {
        _sceneView.debugOptions = ARSCNDebugOptionShowFeaturePoints;
    }
    
    [HKTool hiddeHudView];
}

- (void)hiddenLineNode:(BOOL)hidden
{
    if( _line )
    {
        _line.startNode.hidden = hidden;
        _line.endNode.hidden = hidden;
        _line.lineNode.hidden = hidden;
        _line.textNode.hidden = hidden;
        _line.textWrapNode.hidden = hidden;
    }
    
    for (LineNode *line in self.lines)
    {
        line.startNode.hidden = hidden;
        line.endNode.hidden = hidden;
        line.lineNode.hidden = hidden;
        line.textNode.hidden = hidden;
        line.textWrapNode.hidden = hidden;
        
        //转换成UIKit坐标(屏幕坐标)
        SCNVector3 s =  [_sceneView projectPoint:line.startNode.position];
        SCNVector3 e = [_sceneView projectPoint:line.endNode.position ];
        
        //图片坐标，不乘以2表示的屏幕像素坐标,乘以2是实际图片分辨率坐标，iphone7保存图片尺寸为 750*1334
        NSLog(@"(%d,%d),(%d,%d)",(int)s.x * 2,(int)s.y * 2,(int)e.x * 2,(int)e.y*2);
    }
}

#pragma mark- 保存图像到相册
- (void)saveAlbumWith:(UIImage*)image
{
    [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
        
        [PHAssetChangeRequest creationRequestForAssetFromImage:image];
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (success) {
                [HKTool showToastWithMessage:@"图片保存成功"];
            }else{
                [HKTool showToastWithMessage:@"图片保存失败"];
            }
        });
    }];
}

//请求权限
- (void)authorizeWithCompletion:(void(^)(BOOL granted,BOOL firstTime))completion
{
    PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
    
    switch (status) {
        case PHAuthorizationStatusAuthorized:
        {
            if (completion) {
                completion(YES,NO);
            }
        }
            break;
        case PHAuthorizationStatusRestricted:
        case PHAuthorizationStatusDenied:
        {
            if (completion) {
                completion(NO,NO);
            }
        }
            break;
        case PHAuthorizationStatusNotDetermined:
        {
            [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                if (completion) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        completion(status == PHAuthorizationStatusAuthorized,YES);
                    });
                }
            }];
        }
            break;
        default:
        {
            if (completion) {
                completion(NO,NO);
            }
        }
            break;
    }
}

#pragma mark- focusSquare private
- (void)setupFocusSquare
{
    if (_focusSquare) {
        _focusSquare.hidden = YES;
        [_focusSquare removeFromParentNode];
    }
    self.focusSquare = [[FocusSquare alloc]init];
    [_sceneView.scene.rootNode addChildNode:_focusSquare];
}


//显示效果，暂时不要
- (void)updateFocusSquare
{
//    if (_showDebugVisuals) {
//
//        [_focusSquare unhide];
//    }else
//    {
//        [_focusSquare hide];
//    }
//
//    CGPoint mid = CGPointMake(CGRectGetMidX(self.sceneView.bounds),CGRectGetMidY(self.sceneView.bounds));
//
//    WorldPostion *ps = [self worldPositionFromScreenPosition:mid objectPos:self.focusSquare.position infinitePlane:NO];
//
//
//    if (ps) {
//
//        self.focusSquare
//    }
    
}

#pragma mark- Position Measure

- (WorldPostion*)worldPositionFromScreenPosition:(CGPoint)postion
                                       objectPos:(SCNVector3)objectPos
                                   infinitePlane:(BOOL)infinitePlane
{
    NSArray<ARHitTestResult *> * planeHitTestResults = [_sceneView hitTest:postion types:ARHitTestResultTypeExistingPlaneUsingExtent];
    
    if ( planeHitTestResults && planeHitTestResults.count > 0 ) {
        
        ARHitTestResult *result = planeHitTestResults.firstObject;
        
        matrix_float4x4 worldTransform  = result.worldTransform;
        
        SCNVector3 planeHitTestPosition = SCNVector3Make(worldTransform.columns[3].x, worldTransform.columns[3].y, worldTransform.columns[3].z);
        
        WorldPostion *ps = [[WorldPostion alloc]init];
        ps.position = planeHitTestPosition;
        ps.planeAnchor = [result.anchor isKindOfClass:[ARPlaneAnchor class]] ? (ARPlaneAnchor*)result.anchor : nil;
        
        ps.hitAPlane = YES;
        
        return ps;
    }
    
    SCNVector3 featureHitTestPosition = SCNVector3Zero;
    BOOL highQualityFeatureHitTestResult = NO;
    
    NSArray<FeatureHitTestResult*>* highQualityfeatureHitTestResults =  [_sceneView hitTestWithFeatures:postion coneOpeningAngleInDegrees:5 minDistance:0.1 maxDistance:50.0 maxResults:INT_MAX];
    
    
    NSArray<SCNVector3OBJ*>* featureCloud = [_sceneView fliterWithFeatures:highQualityfeatureHitTestResults];
    
    if (featureCloud.count >= 3) {
        
        NSMutableArray<NSValue*> *warpFeatures = [NSMutableArray arrayWithCapacity:featureCloud.count];
        
        for (int i = 0; i < featureCloud.count; i++) {
            NSValue *v = [NSValue valueWithSCNVector3:featureCloud[i].s];
            [warpFeatures addObject:v];
        }
        
        // 根据特征点进行平面推定
        SCNVector4 detectPlane = [self planeDetectWithFeatureCloud:warpFeatures];
        
        SCNVector3 planePoint = SCNVector3Zero;
        
        if (detectPlane.x != 0) {
            planePoint = SCNVector3Make(detectPlane.w/detectPlane.x,0,0);
        }else if (detectPlane.y != 0){
            planePoint = SCNVector3Make(0,detectPlane.w/detectPlane.y,0);
        }else {
            planePoint = SCNVector3Make(0,0,detectPlane.w/detectPlane.z);
        }
        
        HitTestRay* ray = [_sceneView hitTestRayFromScreenPos:postion];
        
        
        SCNVector3OBJ *crossPoint = [self planeLineIntersectPoint:SCNVector3Make(detectPlane.x,detectPlane.y,detectPlane.z)
                                                       planePoint:planePoint
                                                       lineVector:ray.direction
                                                        linePoint:ray.origin];
        
        if (crossPoint != nil) {
            WorldPostion *ps = [[WorldPostion alloc]init];
            ps.position = crossPoint.s;
            ps.planeAnchor = nil;
            ps.hitAPlane = NO;
            return ps;
        }else{
            WorldPostion *ps = [[WorldPostion alloc]init];
            SCNVector3 average = [Utilities SCNVector3Average:featureCloud];
            ps.position = average;
            ps.planeAnchor = nil;
            ps.hitAPlane = NO;
            return ps;
        }
        
    }
    
    if (featureCloud.count > 0) {
        
        featureHitTestPosition = [Utilities SCNVector3Average:featureCloud];
        highQualityFeatureHitTestResult = YES;
        
    }
    else if( highQualityfeatureHitTestResults.count > 0 )
    {
        for (int i = 0; i < highQualityfeatureHitTestResults.count; i++) {
            
            featureHitTestPosition.x += highQualityfeatureHitTestResults[i].position.x;
            featureHitTestPosition.y += highQualityfeatureHitTestResults[i].position.y;
            featureHitTestPosition.z += highQualityfeatureHitTestResults[i].position.z;
        }
        featureHitTestPosition.x /= highQualityfeatureHitTestResults.count;
        featureHitTestPosition.y /= highQualityfeatureHitTestResults.count;
        featureHitTestPosition.z /= highQualityfeatureHitTestResults.count;
        highQualityFeatureHitTestResult = YES;
    }
    
    
    // 3. If desired or necessary (no good feature hit test result): Hit test
    //    against an infinite, horizontal plane (ignoring the real world).
    if (infinitePlane || !highQualityFeatureHitTestResult) {
        
        SCNVector3 pointOnPlane = objectPos;
        
        SCNVector3OBJ* pointOnInfinitePlane =  [_sceneView hitTestWithInfiniteHorizontalPlane:postion pointOnPlane:pointOnPlane];
        
        if (pointOnInfinitePlane) {
            
            WorldPostion *ps = [[WorldPostion alloc]init];
            ps.position = pointOnInfinitePlane.s;
            ps.planeAnchor = nil;
            ps.hitAPlane = NO;
            return ps;
        }
    }
    
    // -------------------------------------------------------------------------------
    // 4. If available, return the result of the hit test against high quality
    //    features if the hit tests against infinite planes were skipped or no
    //    infinite plane was hit.
    
    if (highQualityFeatureHitTestResult) {
        WorldPostion *ps = [[WorldPostion alloc]init];
        
        ps.position = featureHitTestPosition;
        ps.planeAnchor = nil;
        ps.hitAPlane = NO;
        return ps;
    }
    
    // -------------------------------------------------------------------------------
    // 5. As a last resort, perform a second, unfiltered hit test against features.
    //    If there are no features in the scene, the result returned here will be nil.
    

    NSArray<FeatureHitTestResult*>* unfilteredFeatureHitTestResults = [_sceneView hitTestWithFeatures:postion];
    
    if (unfilteredFeatureHitTestResults.count > 0) {
        
        WorldPostion *ps = [[WorldPostion alloc]init];
        
        ps.position = unfilteredFeatureHitTestResults[0].position;
        ps.planeAnchor = nil;
        ps.hitAPlane = NO;
        return ps;
    }
    
    return nil;
}


- (SCNVector4)planeDetectWithFeatureCloud:(NSArray<NSValue*>*)featureCloud
{
    return [PlaneDetector detectPlaneWithPoints:featureCloud];
}

/// 根据直线上的点和向量及平面上的点和法向量计算交点
///
/// - Parameters:
///   - planeVector: 平面法向量
///   - planePoint: 平面上一点
///   - lineVector: 直线向量
///   - linePoint: 直线上一点
/// - Returns: 交点
-(SCNVector3OBJ*) planeLineIntersectPoint:(SCNVector3)planeVector
                               planePoint:(SCNVector3)planePoint
                               lineVector: (SCNVector3)lineVector
                                linePoint: (SCNVector3)linePoint
{
    CGFloat vpt = planeVector.x*lineVector.x + planeVector.y*lineVector.y + planeVector.z*lineVector.z;
    
    if(vpt != 0)
    {
        CGFloat t = ((planePoint.x-linePoint.x)*planeVector.x + (planePoint.y-linePoint.y)*planeVector.y + (planePoint.z-linePoint.z)*planeVector.z)/vpt;
        SCNVector3 cross = SCNVector3Make(linePoint.x + lineVector.x*t, linePoint.y + lineVector.y*t, linePoint.z + lineVector.z*t);
        
        
        SCNVector3 sub = [Utilities SCNVector3Sub:cross right:linePoint];
        
        if ([Utilities SCNVector3Length:sub] < 5 ) {
            return [SCNVector3OBJ objectWith:cross];
        }
    }
    return nil;
}

- (void)updateLineNode
{
    WorldPostion *ps = [self worldPositionFromScreenPosition:self.indicator.center objectPos:SCNVector3Zero infinitePlane:NO];
    
    SCNVector3 p = ps.position;
        if (!SCNVector3EqualToVector3(p, SCNVector3Zero))
//    if(ps)
    {
        ARCamera *camera = self.sceneView.session.currentFrame.camera;
        SCNVector3 cameraPos = [Utilities positionFromTransform:camera.transform];
        
        CGFloat distance = [Utilities distanceFromPos:cameraPos to:p];
        if (distance < 0.05 && _line == nil) {
            [self updateView:NO];
            return;
        }
        [self updateView:YES];
        
        //绘制线段并返回线段长度
        CGFloat length = [self.line updatePosition:p camera:self.sceneView.session.currentFrame.camera];
    }
    
    if ( self.sceneView.session.currentFrame ) {
        
        ARCamera *camera = self.sceneView.session.currentFrame.camera;
        if (camera) {
            SCNVector3 cameraPos = [Utilities positionFromTransform:camera.transform];
            self.cameraNode.position = cameraPos;
        }
    }
}

#pragma mark- ARSCNViewDelegate

- (void)renderer:(id<SCNSceneRenderer>)renderer updateAtTime:(NSTimeInterval)time
{
    dispatch_async(dispatch_get_main_queue(), ^{
        
        [self updateFocusSquare];
        [self updateLineNode];
    });
}

- (void)renderer:(id<SCNSceneRenderer>)renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (anchor && [anchor isKindOfClass:[ARPlaneAnchor class]]) {
            [self addPlaneWithNode:node anchor:(ARPlaneAnchor*)anchor];
        }
    });
}

- (void)renderer:(id<SCNSceneRenderer>)renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (anchor && [anchor isKindOfClass:[ARPlaneAnchor class]]) {
            [self updatePlaneWithAnchor:(ARPlaneAnchor*)anchor];
        }
    });
}

- (void)renderer:(id<SCNSceneRenderer>)renderer didRemoveNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (anchor && [anchor isKindOfClass:[ARPlaneAnchor class]]) {
            [self removePlane:(ARPlaneAnchor*)anchor];
        }
    });
}

- (void)session:(ARSession *)session cameraDidChangeTrackingState:(ARCamera *)camera
{
//    let tips:String = camera.trackingState.presentationString

    switch (camera.trackingState) {
        case ARTrackingStateNotAvailable:
        {
            [HKTool showToastWithMessage:@"设备不支持"];
        }
            break;
        case ARTrackingStateLimited:
        {
            switch (camera.trackingStateReason) {
                case ARTrackingStateReasonExcessiveMotion:
                    [HKTool showToastWithMessage:@"手机移动过快"];
                    break;
                case ARTrackingStateReasonInitializing:
                case ARTrackingStateReasonInsufficientFeatures:
                {
                    [HKTool showToastWithMessage:@"特征点初始化中"];
                }
                    break;
                    
                default:
                    break;
            }
        }
            break;
        default:
            break;
    }
}

- (void)session:(ARSession *)session didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError:%@",error);
}

- (void)sessionInterruptionEnded:(ARSession *)session
{
    
}
- (void)sessionWasInterrupted:(ARSession *)session
{
    
}

#pragma mark -- 属性
- (NSMutableArray<LineNode*>*)lines
{
    if (!_lines) {
        _lines = [NSMutableArray array];
    }
    return _lines;
}

- (NSMutableDictionary<ARPlaneAnchor*,Plane*> *)planes
{
    if (!_planes) {
        _planes = [NSMutableDictionary dictionary];
    }
    return _planes;
}

/**
 This is called when a new frame has been updated.
 
 @param session The session being run.
 @param frame The frame that has been updated.
 */
- (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame
{
    NSLog(@"session:(ARSession *)session didUpdateFrame:(ARFrame *)frame");
    CVPixelBufferRef ref = frame.capturedImage;
    
    static NSInteger num = 0;
    num++;
    
    if (num == 500) {
        
        UIImage *img  = [self convertPixBuffer:ref];
        
        if (img) {
            [self saveAlbumWith:img];
        }
    }
}

- (UIImage*)convertPixBuffer:(CVPixelBufferRef) ref
{
    CIImage *cimg = [[CIImage alloc]initWithCVImageBuffer:ref];
    
    CIContext *temporaryContext = [[CIContext alloc]initWithOptions:nil];
    
   CGImageRef cgImg = [temporaryContext createCGImage:cimg fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(ref), CVPixelBufferGetHeight(ref))];
    
    if (cgImg) {

        UIImage *img = [[UIImage alloc]initWithCGImage:cgImg];
        
        return img;
    }
    return nil;
}

    
    
    
//    let ciImage = CIImage(cvPixelBuffer: buffer)
//       let temporaryContext = CIContext(options: nil)
//       if let temporaryImage = temporaryContext.createCGImage(ciImage, from: CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(buffer), height: CVPixelBufferGetHeight(buffer)))
//       {
//           let capturedImage = UIImage(cgImage: temporaryImage)
//           return capturedImage
////       }
//}

@end

